package org.anachronos.jeep.ui.trace;

import org.anachronos.jeep.model.trace.Class;
import org.anachronos.jeep.model.trace.Invocation;
import org.anachronos.jeep.model.trace.Method;
import org.anachronos.jeep.model.trace.MethodInvocation;
import org.anachronos.jeep.model.trace.SqlStatementExecution;
import org.anachronos.jeep.model.trace.ThreadCallStack;
import org.anachronos.jeep.model.trace.util.MetricsHelper;
import org.anachronos.jeep.model.trace.util.TraceSwitch;
import org.anachronos.jeep.ui.trace.util.SqlStatementStyler;

public class TraceColumnSwitch extends TraceSwitch<Comparable<?>> {
	private int columnIndex;
	
	public void setColumnIndex(final int columnIndex) {
		this.columnIndex = columnIndex;
	}
	
	public int getColumnIndex() {
		return columnIndex;
	}
	
	@Override
	public Comparable<?> caseMethodInvocation(final MethodInvocation object) {
		final Method method = object.getMethod();
		switch(columnIndex) {
		case 0:
			final Class clazz = (Class)method.eContainer();
			return clazz.getName();
		case 1:
			final StringBuffer buffer = new StringBuffer(method.getName()).append("(");
			String delim = "";
			for (Class argType : method.getArgumentTypes()) {
				buffer.append(delim);
				delim = ",";
				buffer.append(argType.getName());
			}
			buffer.append("):").append(method.getReturnType().getName());
			return buffer.toString();
		default:
			return super.caseMethodInvocation(object);
		}
	}
	
	@Override
	public Comparable<?> caseSqlStatementExecution(final SqlStatementExecution object) {
		switch (columnIndex) {
		case 0:
			final String className = object.getClassName();
			final int lastIndexOf = className.lastIndexOf(".");
			return lastIndexOf != -1 ? className.substring(lastIndexOf + 1) : className;
		case 1:
			return SqlStatementStyler.getStyledStatement(object).getString();
		default:
			return super.caseSqlStatementExecution(object);
		}
	}
	
	@Override
	public Comparable<?> caseThreadCallStack(final ThreadCallStack object) {
		if (columnIndex == 0) {
			return object.getName();
		}
		return super.caseThreadCallStack(object);
	}
	
	@Override
	public Comparable<?> caseInvocation(Invocation object) {
		switch (columnIndex) {
		case 0:
		case 1:
			return "";
		case 2:
			return MetricsHelper.getSelfMetrics(object).getTotalTimeNs();
		case 3:
			return MetricsHelper.getSelfTimePercent(object);
		case 4:
			return MetricsHelper.getMetrics(object).getTotalTimeNs();
		case 5:
			return MetricsHelper.getTotalTimePercent(object);
		case 6:
			return MetricsHelper.getMetrics(object).getCalls();
		}
		return super.caseInvocation(object);
	}
}